React Hooks の useReducer と向き合う
useState で誤魔化していたのだけど、使ってみたら案外便利かも?とおもってちょっと素振りした
仕事で Apollo を使っていて便利なのだけど、別件では未だに REST なので、Apollo っぽいインターフェースで REST を叩けることを目標にする code:index.tsx
enum DATA_FETCH_ACTION {
FETCH_COMPLETE = 'FETCH_COMPLETE'
}
interface DataFetchState<T> {
loading: boolean
error: Maybe<Error>
data: Maybe<T>
}
interface DataFetchAction<T> {
type: DATA_FETCH_ACTION
payload: T
error?: boolean
}
const dataFetchReducer = <T>(
state: DataFetchState<T>,
action: DataFetchAction<T>
): DataFetchState<T> => {
switch (action.type) {
case DATA_FETCH_ACTION.FETCH_COMPLETE: {
return {
...state,
loading: false,
data: action.payload
}
}
}
return state
}
const useRequest = <T>(url: string) => {
React.Reducer<DataFetchState<T>, DataFetchAction<T>>
(dataFetchReducer, {
loading: true,
error: null,
data: null
})
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(json => {
if (json.data) {
dispatch({
type: DATA_FETCH_ACTION.FETCH_COMPLETE,
payload: json.data as T
})
} else {
// TODO
}
})
}, [])
return state
}
ざっくり共通リクエスト部分
code:index.tsx
export const useFoo = ({ id }: Params) {
const state = useRequest<FooResponse>(/api/foo/${id})
return state
}
こんな感じで hook を用意しておくと、コンポーネント側から Apollo ライクに呼び出してハンドリングしてあげるだけでアプリケーションが組み立てられて便利
まだエラーハンドリングとかはやってないのでおいおいということで...